package cn.iocoder.yudao.module.erp.service.suppliersendorder;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.module.erp.controller.admin.suppliersendorder.vo.SupplierSendOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.suppliersendorder.vo.SupplierSendOrderRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.suppliersendorder.vo.SupplierSendOrderSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.suppliersendorderitem.vo.SupplierVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purpurchaseorder.PurPurchaseOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purpurchaseorderitem.PurPurchaseOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.suppliersendorder.SupplierSendOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.suppliersendorderitem.SupplierSendOrderItemDO;
import cn.iocoder.yudao.module.erp.dal.mysql.purpurchaseorder.PurPurchaseOrderMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.purpurchaseorderitem.PurPurchaseOrderItemMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.suppliersendorder.SupplierSendOrderMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.suppliersendorderitem.SupplierSendOrderItemMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;

/**
 * ERP 随货同行单 Service 实现类
 * @author ls
 */
@Service
@Validated
public class SupplierSendOrderServiceImpl implements SupplierSendOrderService {

    @Resource
    private SupplierSendOrderMapper supplierSendOrderMapper;
    @Resource
    private SupplierSendOrderItemMapper supplierSendOrderItemMapper;
    @Resource
    private PurPurchaseOrderMapper purPurchaseOrderMapper;
    @Resource
    private PurPurchaseOrderItemMapper purPurchaseOrderItemMapper;
    @Resource
    private ErpNoRedisDAO noRedisDAO;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSupplierSendOrder(SupplierSendOrderSaveReqVO createReqVO) {
        // 判断数量修改状态
        // 根据订单编号查询订单总数量
        List<SupplierSendOrderItemDO> supplierSendOrderItemDO1 = getSupplierSendOrderItemListByPurchaseOrderId(createReqVO.getPurchaseOrderId());
        List<SupplierSendOrderItemDO> supplierSendOrderItemDO2 = new ArrayList<>();
        for (SupplierSendOrderItemDO supplierSendOrderItem : createReqVO.getSupplierSendOrderItems()) {
            supplierSendOrderItemDO2.add(supplierSendOrderItem);
        }
        if (supplierSendOrderItemDO1 !=null && supplierSendOrderItemDO1.size()>0){
            supplierSendOrderItemDO2.addAll(supplierSendOrderItemDO1);
        }
        // 获取随库同行单总数量
        BigDecimal supplierSendOrderCount = new BigDecimal("0");
        for (SupplierSendOrderItemDO supplierSendOrderItemDO : supplierSendOrderItemDO2) {
            supplierSendOrderCount = supplierSendOrderCount.add(supplierSendOrderItemDO.getCount());
        }
        // 获取订单中数量
        BigDecimal purPurchaseOrderCount = new BigDecimal("0");;
        PurPurchaseOrderDO purPurchaseOrder = purPurchaseOrderMapper.getPurPurchaseOrderByPurchaseOrderId(createReqVO.getPurchaseOrderId());
        List<PurPurchaseOrderItemDO> purPurchaseOrderItemDOS = purPurchaseOrderItemMapper.selectListByPurchaseOrderId(purPurchaseOrder.getId().toString());
        for (PurPurchaseOrderItemDO purPurchaseOrderItemDO : purPurchaseOrderItemDOS) {
            for (SupplierSendOrderItemDO supplierSendOrderItemDO : supplierSendOrderItemDO2) {
                if (purPurchaseOrderItemDO.getProductId().equals(supplierSendOrderItemDO.getProductId())) {
                    if(supplierSendOrderItemDO.getCount().compareTo(purPurchaseOrderItemDO.getCount())==1){
                        throw exception(SUPPLIER_DY_PUR_PURCHASE);
                    }
                }
            }
            purPurchaseOrderCount = purPurchaseOrderCount.add(purPurchaseOrderItemDO.getCount());
        }
        if (supplierSendOrderCount.compareTo(purPurchaseOrderCount)==1){
            throw exception(SUPPLIER_DY_PUR_PURCHASE);
        }
        // 查询订单，修改订单状态
        if (supplierSendOrderCount.compareTo(purPurchaseOrderCount)==0){
            purPurchaseOrder.setStatus(2);
        }else {
            purPurchaseOrder.setStatus(1);
        }
        purPurchaseOrderMapper.updateById(purPurchaseOrder);
        // 插入
        SupplierSendOrderDO supplierSendOrder = BeanUtils.toBean(createReqVO, SupplierSendOrderDO.class);
        //  随库同行单编号，并校验唯一性
        String no = noRedisDAO.generate(ErpNoRedisDAO.SUPPLIERSENDORDER_ORDER_NO_PREFIX);
        if (supplierSendOrderMapper.selectByNo(no) != null) {
            throw exception(SEND_ORDER_CHECK_NO_EXISTS);
        }
        supplierSendOrder.setOutOrderId(no);
        supplierSendOrder.setDeptId(purPurchaseOrder.getDeptId());
        supplierSendOrder.setPurchaseOrderId(purPurchaseOrder.getId());
        supplierSendOrder.setSendTime(LocalDateTime.now());
        supplierSendOrder.setStatus(0);
        String id = UUID.randomUUID().toString();
        supplierSendOrder.setId(id);
        supplierSendOrderMapper.insert(supplierSendOrder);
        //计算总价
        for (SupplierSendOrderItemDO supplierSendOrderItem : createReqVO.getSupplierSendOrderItems()) {
            supplierSendOrderItem.setTotalPrice(supplierSendOrderItem.getProductPrice().multiply(supplierSendOrderItem.getCount()));
        }
        // 插入子表
        createSupplierSendOrderItemList(id, createReqVO.getSupplierSendOrderItems());
        // 返回
        return null;
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSupplierSendOrder(SupplierSendOrderSaveReqVO updateReqVO) {
        // 判断数量修改状态
        // 根据订单编号查询订单总数量
       // List<SupplierSendOrderItemDO> supplierSendOrderItemDO1 = getSupplierSendOrderItemListByPurchaseOrderId(updateReqVO.getPurchaseOrderId());
        List<SupplierSendOrderItemDO> supplierSendOrderItemDO2 = updateReqVO.getSupplierSendOrderItems();
//        if (supplierSendOrderItemDO1 !=null && supplierSendOrderItemDO1.size()>0){
//            supplierSendOrderItemDO2.addAll(supplierSendOrderItemDO1);
//        }

        // 获取随库同行单总数量
        BigDecimal supplierSendOrderCount = new BigDecimal("0");
        for (SupplierSendOrderItemDO supplierSendOrderItemDO : supplierSendOrderItemDO2) {
            supplierSendOrderCount = supplierSendOrderCount.add(supplierSendOrderItemDO.getCount());
        }
        // 获取订单中数量
        BigDecimal purPurchaseOrderCount = new BigDecimal("0");;
        PurPurchaseOrderDO purPurchaseOrder = purPurchaseOrderMapper.getPurPurchaseOrderByPurchaseOrderId(updateReqVO.getPurchaseOrderId());
        List<PurPurchaseOrderItemDO> purPurchaseOrderItemDOS = purPurchaseOrderItemMapper.selectListByPurchaseOrderId(purPurchaseOrder.getId().toString());
        for (PurPurchaseOrderItemDO purPurchaseOrderItemDO : purPurchaseOrderItemDOS) {
            for (SupplierSendOrderItemDO supplierSendOrderItemDO : supplierSendOrderItemDO2) {
                if (purPurchaseOrderItemDO.getProductId().equals(supplierSendOrderItemDO.getProductId())) {
                    if(supplierSendOrderItemDO.getCount().compareTo(purPurchaseOrderItemDO.getCount())==1){
                        throw exception(SUPPLIER_DY_PUR_PURCHASE);
                    }
                }
            }
            purPurchaseOrderCount = purPurchaseOrderCount.add(purPurchaseOrderItemDO.getCount());
        }
        if (supplierSendOrderCount.compareTo(purPurchaseOrderCount)==1){
            throw exception(SUPPLIER_DY_PUR_PURCHASE);
        }
        // 查询订单，修改订单状态

        if (supplierSendOrderCount.compareTo(purPurchaseOrderCount)==0){
            purPurchaseOrder.setStatus(2);
        }else {
            purPurchaseOrder.setStatus(1);
        }
        purPurchaseOrderMapper.updateById(purPurchaseOrder);

        // 查询随库同行单
        List<SupplierSendOrderItemDO> supplierSendOrderItems = updateReqVO.getSupplierSendOrderItems();
//        if (supplierSendOrderItems !=null && supplierSendOrderItems.size()>0){
//            supplierSendOrderItemMapper.insertOrUpdate(supplierSendOrderItems);
//        }
        List<SupplierSendOrderItemDO> insertList = new ArrayList<>();
        List<SupplierSendOrderItemDO> updateList = new ArrayList<>();

        for (SupplierSendOrderItemDO item : supplierSendOrderItems) {
            if (item.getId() != null && item.getId() > 0) {
                // 有 ID，视为更新
                updateList.add(item);
            } else {
                // 无 ID，视为新增
                insertList.add(item);
            }
        }
        // 执行更新
        if (!updateList.isEmpty()) {
            supplierSendOrderItemMapper.updateBatch(updateList); // 确保每个对象都有 id
        }
        // 执行新增
        if (!insertList.isEmpty()) {
            // 设置外键（outOrderId）等公共字段（如果尚未设置）
            String outOrderId = updateReqVO.getSupplierSendOrderItems().get(0).getOutOrderId(); // 第一个子表的outOrderId
            for (SupplierSendOrderItemDO item : insertList) {
                item.setOutOrderId(outOrderId);
                item.setTotalPrice(item.getProductPrice().multiply(item.getCount())); // 计算总价
            }

            supplierSendOrderItemMapper.insertBatch(insertList);
        }

    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void printSupplierSendOrder(SupplierSendOrderSaveReqVO updateReqVO) {
        // 校验存在
        validateSupplierSendOrderExists(updateReqVO.getId());
        SupplierSendOrderDO updateObj = BeanUtils.toBean(updateReqVO, SupplierSendOrderDO.class);
        supplierSendOrderMapper.updateById(updateObj);
        // 修改订单打印状态
        PurPurchaseOrderDO purPurchaseOrderDO = purPurchaseOrderMapper.selectById(updateObj.getPurchaseOrderId());
        purPurchaseOrderDO.setPrintStatus("1");
        purPurchaseOrderMapper.updateById(purPurchaseOrderDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSupplierSendOrder(String id) {
        // 校验存在
        validateSupplierSendOrderExists(id);
        // 删除
        supplierSendOrderMapper.deleteById(id);

        // 删除子表
        deleteSupplierSendOrderItemByOutOrderId(id);
    }

    private void validateSupplierSendOrderExists(String id) {
        if (supplierSendOrderMapper.selectById(id) == null) {
            throw exception(SUPPLIER_SEND_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public SupplierSendOrderDO getSupplierSendOrder(String id) {
        return supplierSendOrderMapper.selectById(id);
    }

    @Override
    public PageResult<SupplierSendOrderDO> getSupplierSendOrderPage(SupplierSendOrderPageReqVO pageReqVO) {
        return supplierSendOrderMapper.selectPage(pageReqVO);
    }

    // ==================== 子表（ERP 随货同行单项） ====================

    @Override
    public List<SupplierSendOrderItemDO> getSupplierSendOrderItemListByOutOrderId(String outOrderId) {
        return supplierSendOrderItemMapper.selectListByOutOrderId(outOrderId);
    }

    private void createSupplierSendOrderItemList(String outOrderId, List<SupplierSendOrderItemDO> list) {
        list.forEach(o -> o.setOutOrderId(outOrderId));
        supplierSendOrderItemMapper.insertBatch(list);
    }

    private void updateSupplierSendOrderItemList(String outOrderId, List<SupplierSendOrderItemDO> list) {
        deleteSupplierSendOrderItemByOutOrderId(outOrderId);
		list.forEach(o -> o.setId(null).setUpdater(null).setUpdateTime(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createSupplierSendOrderItemList(outOrderId, list);
    }

    private void deleteSupplierSendOrderItemByOutOrderId(String outOrderId) {
        supplierSendOrderItemMapper.deleteByOutOrderId(outOrderId);
    }
    @Override
    public PageResult<SupplierSendOrderItemDO> getSupplierSendOrderItemPage(PageParam pageReqVO,String outOrderId) {
        return supplierSendOrderItemMapper.selectPage(pageReqVO, outOrderId);
    }

    @Override
    public Long createSupplierSendOrderItem(SupplierSendOrderItemDO supplierSendOrderItem) {
        supplierSendOrderItemMapper.insert(supplierSendOrderItem);
        return supplierSendOrderItem.getId();
    }



    @Override
    public void updateSupplierSendOrderItem(SupplierSendOrderItemDO supplierSendOrderItem) {
        // 校验存在
        validateSupplierSendOrderItemExists(supplierSendOrderItem.getId());
        // 更新
        supplierSendOrderItem.setUpdater(null).setUpdateTime(null); // 解决更新情况下：updateTime 不更新
        supplierSendOrderItemMapper.updateById(supplierSendOrderItem);
    }

    @Override
    public void deleteSupplierSendOrderItem(Long id) {
        // 校验存在
        validateSupplierSendOrderItemExists(id);
        // 删除
        supplierSendOrderItemMapper.deleteById(id);
    }

    @Override
    public SupplierSendOrderItemDO getSupplierSendOrderItem(Long id) {
        return supplierSendOrderItemMapper.selectById(id);
    }

    @Override
    public List<SupplierSendOrderItemDO> getSupplierSendOrderItemListByPurchaseOrderId(String puchaseOrderId){
        // 根据订单id先查随货同行单
        List<SupplierSendOrderDO> supplierSendOrderDOList = supplierSendOrderMapper.getSupplierSendOrderDOListByByOutPurchaseOrderId(puchaseOrderId);
        // 若为空  返回
        if (supplierSendOrderDOList == null || supplierSendOrderDOList.size() == 0) {
            return null;
        }
        List<String> ids = convertList(supplierSendOrderDOList, SupplierSendOrderDO::getId);

        List<SupplierSendOrderItemDO> sendOrderItemDOS = supplierSendOrderItemMapper.selectListByOutOrderIds(ids);

        return sendOrderItemDOS;
    }

    @Override
    public List<SupplierSendOrderItemDO> getSupplierSendOrderItemPrintListByPurchaseOrderId(String puchaseOrderId) {

        // 根据订单id先查随货同行单
        List<SupplierSendOrderDO> supplierSendOrderDOList = supplierSendOrderMapper.getSupplierSendOrderDOPrintListByOutPurchaseOrderId(puchaseOrderId);
        // 若为空  返回
        if (supplierSendOrderDOList == null || supplierSendOrderDOList.size() == 0) {
            return null;
        }
        List<String> ids = convertList(supplierSendOrderDOList, SupplierSendOrderDO::getId);

        List<SupplierSendOrderItemDO> sendOrderItemDOS = supplierSendOrderItemMapper.selectListByOutOrderIds(ids);

        return sendOrderItemDOS;
    }

    /**
     * 根据采购订单ids查询随货同行单
     * @param purchaseOrderIds
     * @return
     */
    @Override
    public List<SupplierSendOrderRespVO> getSupplierSendOrderItemListByPurchaseOrderIds(String[] purchaseOrderIds) {
//        根据采购单数组批量查询随货同行单
        List<SupplierSendOrderDO> supplierSendOrderDOList = supplierSendOrderMapper.getSupplierSendOrderItemListByPurchaseOrderIds(purchaseOrderIds);
        return BeanUtils.toBean(supplierSendOrderDOList, SupplierSendOrderRespVO.class);
    }

    /**
     * 根据入库单id查询随货同行单
     * @param inId
     * @return
     */
    @Override
    public List<SupplierSendOrderRespVO> getSupplierSendOrderListByInId(String inId) {
        List<SupplierSendOrderDO> supplierSendOrderList = supplierSendOrderMapper.selectList(new QueryWrapperX<SupplierSendOrderDO>().eq("pri_in_id", inId));
        return BeanUtils.toBean(supplierSendOrderList, SupplierSendOrderRespVO.class);
    }

    @Override
    public List<SupplierSendOrderItemDO> getItemListByOutOrderId(String outOrderId) {
        // 查询随货同行单项详情
        return supplierSendOrderItemMapper.selectListByOutOrderId(outOrderId);
    }

    private void validateSupplierSendOrderItemExists(Long id) {
        if (supplierSendOrderItemMapper.selectById(id) == null) {
            throw exception(SUPPLIER_SEND_ORDER_ITEM_NOT_EXISTS);
        }
    }
}